<?php

class MprankScript extends ScriptBase
{
	private $mongo = null;
	private $mysql = null;
	private $readCollection = null;
	private $articleCollection = null;

	public function __construct()
	{
		$this->mongo = new MongoClient("mongodb://newbee:9^4%NbAdwS@115.28.18.40:27017");
		$this->mysql = n_api('mysql')->cname('weixin');
		$this->readCollection = $this->mongo->selectDB('weixin')->selectCollection('read');
		$this->articleCollection = $this->mongo->selectDB('weixin')->selectCollection('article');
	}

	private function handle_mprank_by_day($result, $category, $stime)
	{
		foreach ($result as $wxid => $value) {
			$checkExists = $this->mysql->fetchFirst("select id from mprank_day where wxid = '$wxid' and daytime = $stime");
			if (count($checkExists) > 0) {
				$value['utime'] = time();
				$where = "id = {$checkExists['id']}";
				$this->mysql->update('mprank_day', $value, $where);
				echo $wxid . " updated successfully\n";
			} else {
				try {
					$time = time();

					$value['wxid'] = $wxid;
					$value['daytime'] = $stime;
					$value['ctime'] = $time;
					$value['utime'] = $time;

					$this->mysql->insert('mprank_day', $value);
					echo $wxid . " add successfully\n";
				} catch (Exception $e) {
					var_dump($e->getMessage());
				}
			}
		}
	}

	public function mprank_by_category_day()
	{
		set_time_limit(0);
		ini_set('memory_limit', '3072M');
		$weixin = n_api('weixin');
		
		$stime = strtotime(date('Y-m-d', strtotime('-1 day')));
		// var_dump(date('Y-m-d', $stime));exit;
		// $stime = 1443628800;
		$etime = $stime + 24 * 3600;

		$categories = $weixin->getCategories();
		
		foreach ($categories as $id => $category) {
			$rs = $weixin->getWxidsByCategoryId($id);
			$wxids = [];
			foreach ($rs as $value)
				$wxids[] = $value['wxid'];

			$rs = $this->articleCollection->aggregate([
				['$match' => ['ptime' => ['$gte' => $stime, '$lt' => $etime], 'wxid' => ['$in'=>$wxids]]],
				['$group' => ['_id' => '$wxid', 'topNum' => ['$sum' => '$isTop'], 'allNum' => ['$sum' => 1]]]
			]);
			$publish = [];
			foreach ($rs['result'] as $value) {
				$publish[$value['_id']] = ['topNum' => $value['topNum'], 'allNum' => $value['allNum']];
			}
			
			$rs = $this->readCollection->aggregate([
				['$match' => ['ptime' => ['$gte' => $stime, '$lt' => $etime], 'wxid' => ['$in' => $wxids]]],
				['$group' => ['_id' => '$wxid', 'allReadNum' => ['$sum' => '$readNum'], 'allLikeNum' => ['$sum' => '$likeNum'], 'maxRead' => ['$max' => '$readNum']]]
			]);
			$allReadLike = [];
			foreach ($rs['result'] as $value) {
				$allReadLike[$value['_id']] = ['allReadNum' => $value['allReadNum'], 'allLikeNum' => $value['allLikeNum'], 'maxRead' => $value['maxRead']];
			}

			$rs = $this->readCollection->aggregate([
				['$match' => ['ptime' => ['$gte' => $stime, '$lt' => $etime], 'wxid' => ['$in' => $wxids], 'isTop' => 1]],
				['$group' => ['_id' => '$wxid', 'topReadNum' => ['$max' => '$readNum']]]
			]);
			$topReads = [];
			foreach ($rs['result'] as $value) {
				$topReads[$value['_id']] = $value['topReadNum'];
			}

			$result = [];
			foreach ($publish as $wxid => $value) {
				$tmp['pub_times'] = $value['topNum'] == 0 ? 1 : $value['topNum'];
				$tmp['pub_num'] = $value['allNum'];
				$tmp['all_read_num'] = $allReadLike[$wxid]['allReadNum'];
				$tmp['all_like_num'] = $allReadLike[$wxid]['allLikeNum'];
				$tmp['head_read_num'] = $topReads[$wxid] == 0 ? 0 : $topReads[$wxid];
				$tmp['average_read_num'] = (int)($allReadLike[$wxid]['allReadNum'] / $value['allNum']);
				$tmp['max_read_num'] = $allReadLike[$wxid]['maxRead'];
				$tmp['weixin_index'] = $this->calculateIndex($tmp['all_read_num'], $tmp['max_read_num'], $tmp['average_read_num'], $tmp['head_read_num'], $tmp['all_like_num'], 'day');

				$result[$wxid] = $tmp;
			}
			$this->handle_mprank_by_day($result, $category, $stime);
		}
	}

	private function calculateIndex($all, $max, $average, $head, $zan, $type)
	{
		if ($type == 'day')
			$n = 1;
		if ($type == 'week')
			$n = 7;

		$allStandard = 8 * 100000 * $n;
		$maxStandard = 100000 * $n;
		$averageStandard = 100000 * $n;
		$headStandard = 100000 * $n;
		$zanStandard = 8 * 10000 * $n;

		$allLog = log($all+1) * 1000 / log($allStandard+1);
		$maxLog = log($max+1) * 1000 / log($maxStandard+1);
		$averageLog = log($average+1) * 1000 / log($averageStandard+1);
		$headLog = log($head+1) * 1000 / log($headStandard+1);
		$zanLog = log($zan+1) * 1000 / log($zanStandard+1);

		$NRI = 0.75 * $allLog + 0.05 * $maxLog + 0.1 * $averageLog + 0.05 * $headLog + 0.05 * $averageLog;
	
		return $NRI;
	}

	public function mprankByCategoryWeek()
	{
		$stime = strtotime('-4 sunday');
		$etime = strtotime('-3 sunday');

		$query = "select wxid, sum(pub_times) as pub_times, sum(pub_num) as pub_num, sum(all_read_num) as all_read_num, sum(all_like_num) as all_like_num, sum(head_read_num) as head_read_num, avg(average_read_num) as average_read_num, max(max_read_num) as max_read_num, avg(weixin_index) as weixin_index from mprank_day where daytime >= $stime and daytime < $etime group by wxid";
		$rs = $this->mysql->select($query);

		$time = time();
		foreach ($rs as $value) {
			$value['weektime'] = $stime;
			$value['ctime'] = $time;
			$value['utime'] = $time;
			$data[] = $value;
		}

		$a = $this->mysql->batchInsert('mprank_week', $data);
		var_dump($a);
	}

	public function weixinTop()
	{
		$categories = n_api('weixin')->getCategories();
		$mprank = n_api('mprank');
		$maxday = $mprank->getMaxRankDay();

		foreach ($categories as $category) {
			$weixinLists[$category['id']] = $mprank->getMprankByCategory($category, $maxday, 'day', 0, 10);
		}
	}
}